package com.andy.service.impl;

import com.andy.customerService.entity.ProcessLeader;
import com.andy.customerService.entity.Road;
import com.andy.customerService.enums.StatusEnum;
import com.andy.customerService.vo.JsonBaseResult;
import com.andy.entity.FlowInfo;
import com.andy.entity.HistoricActivityInstanceEntity;
import com.andy.entity.UserTaskRequest;
import com.andy.feign.AssigneeFeign;
import com.andy.feign.RoadFeign;
import com.andy.service.IActFlowCustomService;
import com.andy.service.ProcessLeaderService;
import com.andy.utils.SecurityUtil;
import com.andy.utils.SpringContextUtil;
//import com.itheima.entity.Evection;
import lombok.extern.slf4j.Slf4j;
import org.activiti.api.process.model.ProcessDefinition;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.api.runtime.shared.query.Page;
import org.activiti.api.runtime.shared.query.Pageable;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;

@Slf4j
@Service
@Transactional
public class ActFlowCommServiceImpl {

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private SecurityUtil securityUtil;
//    @Autowired
//    private UserService userService;
//    @Autowired
//    private EvectionService evectionService;

    @Autowired
    private ProcessRuntime processRuntime;

    @Autowired
    private ProcessLeaderService processLeaderService;

    @Autowired
    private AssigneeFeign assigneeFeign;

    @Autowired
    private RoadFeign roadFeign;

    /**
     * 部署流程定义
     */
    public void saveNewDeploy(FlowInfo flowInfo) {
        Deployment deployment = repositoryService.createDeployment()
                .addClasspathResource(flowInfo.getFilepath()) // 添加bpmn资源
                .name(flowInfo.getFlowkey())
                .deploy();
//        4、输出部署信息
        System.out.println("流程部署id：" + deployment.getId());
        System.out.println("流程部署名称：" + deployment.getName());
    }

    /**
     * 启动流程实例
     */
    public ProcessInstance startProcess(String formKey, String beanName, String bussinessKey, Long id) {
        IActFlowCustomService customService = (IActFlowCustomService) SpringContextUtil.getBean(beanName);
//		修改业务的状态
        customService.startRunTask(id);
        Map<String, Object> variables = customService.setvariables(id);
        variables.put("bussinessKey", bussinessKey);
//		启动流程
        log.info("【启动流程】，formKey ：{},bussinessKey:{}", formKey, bussinessKey);
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(formKey, bussinessKey, variables);
//		流程实例ID
        String processDefinitionId = processInstance.getProcessDefinitionId();
        log.info("【启动流程】- 成功，processDefinitionId：{}", processDefinitionId);
        return processInstance;
    }


    /**
     * 开启流程实例
     *
     * @params: [businessKey]
     * @author: Andy
     * @dateTime: 2022/1/19 12:44
     */
    public JsonBaseResult<Object> startProcessAndy(String businessKey) {
        JsonBaseResult<Object> result = new JsonBaseResult<>();
        //查询流程负责人列表
//        List<ProcessLeader> processLeaders = processLeaderService.findProcessLeaderList();
        List<ProcessLeader> processLeaders = assigneeFeign.findProcessLeaderList();
        //设置各个流程负责人
        //TODO assignee0 获取当前登录用户id，其余负责人从数据库中查询
        Map<String, Object> assigneeMap = new HashMap<>();
        for (ProcessLeader processLeader : processLeaders) {
            String assignee = processLeader.getRole();
            Long UserId = processLeader.getUserId();
            switch (assignee) {
                case "assignee0":
                    assigneeMap.put("assignee0", UserId);
                    break;
                case "assignee1":
                    assigneeMap.put("assignee1", UserId);
                    break;
                case "assignee2":
                    assigneeMap.put("assignee2", UserId);
                    break;
                case "assignee3":
                    assigneeMap.put("assignee3", UserId);
                    break;
                case "assignee4":
                    assigneeMap.put("assignee4", UserId);
                    break;
                default:
                    break;
            }
        }


        //启动流程实例
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("workOrder-2", businessKey, assigneeMap);
//		流程实例ID
        String processDefinitionId = processInstance.getProcessDefinitionId();
        log.info("【启动流程】- 成功，processDefinitionId：{}", processDefinitionId);
        result.setResultStatus(StatusEnum.SUCCEED);
        return result;
    }

    /**
     * 查看个人任务列表
     */
    public List<Map<String, Object>> myTaskList(String userid, String businessKey) {

        /**
         * 根据负责人id  查询任务
         */
        TaskQuery taskQuery = taskService.createTaskQuery().taskAssignee(userid).processInstanceBusinessKey(businessKey);

        List<Task> list = taskQuery.orderByTaskCreateTime().desc().list();

        List<Map<String, Object>> listmap = new ArrayList<Map<String, Object>>();
        for (Task task : list) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("taskid", task.getId());
            map.put("taskname", task.getName());
            map.put("description", task.getDescription());
            map.put("priority", task.getPriority());
            map.put("owner", task.getOwner());
            map.put("assignee", task.getAssignee());
            map.put("delegationState", task.getDelegationState());
            map.put("processInstanceId", task.getProcessInstanceId());
            map.put("executionId", task.getExecutionId());
            map.put("processDefinitionId", task.getProcessDefinitionId());
            map.put("createTime", task.getCreateTime());
            map.put("taskDefinitionKey", task.getTaskDefinitionKey());
            map.put("dueDate", task.getDueDate());
            map.put("category", task.getCategory());
            map.put("parentTaskId", task.getParentTaskId());
            map.put("tenantId", task.getTenantId());

//            User userInfo = userService.findOneUserById(Long.valueOf(task.getAssignee()));
//            map.put("assigneeUser", userInfo.getUsername());
            listmap.add(map);
        }

        return listmap;
    }

    /**
     * 查看个人任务信息
     */
    public List<Map<String, Object>> myTaskInfoList(String userid) {

        /**
         * 根据负责人id  查询任务
         */
        TaskQuery taskQuery = taskService.createTaskQuery().taskAssignee(userid);

        List<Task> list = taskQuery.orderByTaskCreateTime().desc().list();

        List<Map<String, Object>> listmap = new ArrayList<Map<String, Object>>();
        for (Task task : list) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("taskid", task.getId());
            map.put("assignee", task.getAssignee());
            map.put("processInstanceId", task.getProcessInstanceId());
            map.put("executionId", task.getExecutionId());
            map.put("processDefinitionId", task.getProcessDefinitionId());
            map.put("createTime", task.getCreateTime());
            ProcessInstance processInstance = runtimeService
                    .createProcessInstanceQuery()
                    .processInstanceId(task.getProcessInstanceId())
                    .singleResult();
            if (processInstance != null) {
                String businessKey = processInstance.getBusinessKey();
                if (!StringUtils.isBlank(businessKey)) {
                    String type = businessKey.split(":")[0];
                    String id = businessKey.split(":")[1];
//                    if (type.equals("evection")) {
//                        Evection evection = evectionService.findOne(Long.valueOf(id));
//                        User userInfo = userService.findOneUserById(evection.getUserid());
//                        map.put("flowUserName", userInfo.getUsername());
//                        map.put("flowType", "出差申请");
//                        map.put("flowcontent", "出差" + evection.getNum() + "天");
//                    }
                }
            }
            listmap.add(map);
        }

        return listmap;
    }


    /**
     * 完成提交任务
     *
     * @author: Andy
     * @dateTime: 2022/1/19 13:37
     */
    public void completeProcess(UserTaskRequest userTaskRequest) {
        String userId = userTaskRequest.getUserId();
        String taskId = userTaskRequest.getTaskId();
        String remark = userTaskRequest.getRemark();
        String submitType = userTaskRequest.getSubmitType();
        //任务Id 查询任务对象
        Task task = taskService.createTaskQuery().taskId(userTaskRequest.getTaskId()).singleResult();
        if (task == null) {
            log.error("completeProcess - task is null!!");
            return;
        }

        //任务对象  获取流程实例Id
        String processInstanceId = task.getProcessInstanceId();
        //设置审批人的userId
        Authentication.setAuthenticatedUserId(userId);
        //添加记录
        taskService.addComment(taskId, processInstanceId, remark);
        System.out.println("-----------完成任务操作 开始----------");
        System.out.println("任务Id=" + taskId);
        System.out.println("负责人id=" + userId);
        System.out.println("流程实例id=" + processInstanceId);
        //查询用户角色
        ProcessLeader processLeader = assigneeFeign.getRoleByUserId(userId);
        String role = processLeader.getRole();
        String road = "";
        switch (role){
            case "assignee0":
                //查询对应线路
                Road road0 = roadFeign.getRoadByRole(role);
                road = road0.getRoad();
                break;
            case "assignee1":
                //查询对应线路
                Road road1 = roadFeign.getRoadByRole(role);
                road = road1.getRoad();
                break;
            case "assignee2":
                //查询对应线路
                Road road2 = roadFeign.getRoadByRole(role);
                break;
            case "assignee3":
                //查询对应线路
                Road road3 = roadFeign.getRoadByRole(role);
                break;
            case "assignee4":
                //查询对应线路
                Road road4 = roadFeign.getRoadByRole(role);
                break;
            default:
                break;
        }
        //完成办理
        //是否需要选择线路
        if (StringUtils.isNotBlank(road)) {
            Map<String,Object> variables = new HashMap<String,Object>();
            variables.put("road",road);
            taskService.complete(taskId,variables);
        }

        else {
            //是否有审核类型
            if (StringUtils.isNotBlank(submitType)) {
                Map<String,Object> variables = new HashMap<String,Object>();
                variables.put("submitType",submitType);
                taskService.complete(taskId,variables);
            }else {
                taskService.complete(taskId);
            }
        }
        System.out.println("-----------完成任务操作 结束----------");
    }


    /**
     * 执行第一条线路
     * @param userTaskRequest
     *//*
    public void executeRoad1(UserTaskRequest userTaskRequest){
        String userId = userTaskRequest.getUserId();
        String taskId = userTaskRequest.getTaskId();
        String remark = userTaskRequest.getRemark();
        String submitType = userTaskRequest.getSubmitType();
        //任务Id 查询任务对象
        Task task = taskService.createTaskQuery().taskId(userTaskRequest.getTaskId()).singleResult();
        if (task == null) {
            log.error("completeProcess - task is null!!");
            return;
        }

        //任务对象  获取流程实例Id
        String processInstanceId = task.getProcessInstanceId();
        //设置审批人的userId
        Authentication.setAuthenticatedUserId(userId);
        //添加记录
        taskService.addComment(taskId, processInstanceId, remark);
        System.out.println("-----------完成任务操作 开始----------");
        System.out.println("任务Id=" + taskId);
        System.out.println("负责人id=" + userId);
        System.out.println("流程实例id=" + processInstanceId);
        //完成办理
        if (StringUtils.isNotBlank(submitType)) {
            Map<String,Object> variables = new HashMap<String,Object>();
            variables.put("submitType",submitType);
            taskService.complete(taskId,variables);
        }else {
            taskService.complete(taskId);
        }
        System.out.println("-----------完成任务操作 结束----------");
    }

    *//**
     * 执行第二条线路
     * @param userTaskRequest
     *//*
    public void executeRoad2(UserTaskRequest userTaskRequest){

    }*/

    /**
     * 查询历史记录
     *
     * @param businessKey
     */
    public List<HistoricActivityInstanceEntity> searchHistory(String businessKey) {
        List<HistoricProcessInstance> businessList = historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(businessKey).list();
        if (CollectionUtils.isEmpty(businessList)) {
            return null;
        }
//        String processDefinitionId = businessList.get(0).getProcessDefinitionId();
        String processInstanceId = businessList.get(0).getId();

        // 历史相关Service
        List<HistoricActivityInstance> historyList = historyService
                .createHistoricActivityInstanceQuery()
                .processInstanceId(processInstanceId)
                .orderByHistoricActivityInstanceStartTime()
                .asc()
                .list();
        // act_hi_comment 历史意见表
        List<Comment> CommentList = taskService.getProcessInstanceComments(processInstanceId);
        List<HistoricActivityInstanceEntity> historyEntityList = new ArrayList<>();
        for (HistoricActivityInstance history : historyList) {
            if (StringUtils.isBlank(history.getAssignee())) {
                continue;
            }
            HistoricActivityInstanceEntity historyEntity = this.convertEntity(history);
            // 获取审核意见
            Optional<Comment> comment = CommentList.stream().filter(X -> X.getTaskId().equals(history.getTaskId())).findAny();
            comment.ifPresent(value -> historyEntity.setMessage(value.getFullMessage()));
            historyEntityList.add(historyEntity);
            log.info("活动ID:" + history.getActivityId());
            log.info("活动名称:" + history.getActivityName());
            log.info("流程实例ID:" + history.getProcessInstanceId());
            log.info("办理人ID：" + history.getAssignee());
            log.info("备注：" + historyEntity.getMessage());
            log.info("开始时间：" + history.getStartTime());
            log.info("结束时间：" + history.getEndTime());
            log.info("======================================");
//            User user = userService.findOneUserById(Long.valueOf(history.getAssignee()));
//            System.out.println("办理人名字：" + user.getUsername());

        }
        return historyEntityList;
    }

    /**
     * 转换实体类
     *
     * @param param
     * @return
     */
    public HistoricActivityInstanceEntity convertEntity(HistoricActivityInstance param) {
        HistoricActivityInstanceEntity entity = new HistoricActivityInstanceEntity();
        entity.setActivitiId(param.getActivityId());
        entity.setActivitiName(param.getActivityName());
        entity.setProcessInstanceId(param.getProcessInstanceId());
        entity.setAssignee(param.getAssignee());
        entity.setStartTime(param.getStartTime());
        entity.setEndTime(param.getEndTime());
        entity.setTaskId(param.getTaskId());
        entity.setProcessDefinitionId(param.getProcessDefinitionId());
        return entity;
    }


    /**
     * 查询已部署流程
     */
    public void findAllProcess() {

        securityUtil.logInAs("tom");
//        流程定义分页对象
        Page<ProcessDefinition> definitionPage = processRuntime.processDefinitions(Pageable.of(0, 10));
        log.info("当前流程定义总数：{}", definitionPage.getTotalItems());
        for (ProcessDefinition processDefinition : definitionPage.getContent()) {
            System.out.println("======================================");
            log.info("流程定义内容：{}", processDefinition);
            System.out.println("======================================");
        }
    }


}